package top.zhaoyuliu.logbook.client.connect.base;

import java.nio.ByteBuffer;

import org.tio.core.ChannelContext;
import org.tio.core.GroupContext;
import org.tio.core.exception.AioDecodeException;
import org.tio.core.intf.AioHandler;
import org.tio.core.intf.Packet;

import top.zhaoyuliu.logbook.client.connect.packet.LbPacket;

/**
 * 
 * Copyright © 2021 Arain. All rights reserved.
 *
 * @Title: AbstractAioHandler.java
 * @Prject: logbook-client
 * @Package: top.zhaoyuliu.logbook.client.connect.base
 * @Description: <功能详细描述>
 * @author: Arain
 * @date: 2021年1月22日 下午3:21:14
 * @version: V1.0
 */
public abstract class AbstractAioHandler implements AioHandler {
	
	
	@Override
		public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext)
				throws AioDecodeException {
        if (readableLength < LbPacket.HEADER_LENGTH) {
            return null;
        }
        //消息类型
        byte type = buffer.get();

        int bodyLength = buffer.getInt();

        if (bodyLength < 0) {
            throw new AioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext
					.getClientNode());
        }
        int neededLength = LbPacket.HEADER_LENGTH + bodyLength;
        int test = readableLength - neededLength;
        // 不够消息体长度(剩下的buffer组不了消息体)
        if (test < 0) {
            return null;
        }
        LbPacket imPacket = new LbPacket();
        imPacket.setType(type);
        if (bodyLength > 0) {
            byte[] dst = new byte[bodyLength];
            buffer.get(dst);
            imPacket.setBody(dst);
        }
        return imPacket;
    }


    /**
     * 编码：把业务消息包编码为可以发送的ByteBuffer
     * 消息头：type + bodyLength
     * 消息体：byte[]
     */
    @Override
    public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
        LbPacket showcasePacket = (LbPacket) packet;
        byte[] body = showcasePacket.getBody();
        int bodyLen = 0;
        if (body != null) {
            bodyLen = body.length;
        }

        //总长度是消息头的长度+消息体的长度
        int allLen = LbPacket.HEADER_LENGTH + bodyLen;

        ByteBuffer buffer = ByteBuffer.allocate(allLen);
        buffer.order(groupContext.getByteOrder());

        //写入消息类型
        buffer.put(showcasePacket.getType());
        //写入消息体长度
        buffer.putInt(bodyLen);

        //写入消息体
        if (body != null) {
            buffer.put(body);
        }
        return buffer;
    }
}
